﻿
Imports std

Public Class switcher(Of T As IComparable(Of T), AT, OT)
    Public Class condition_action
        Public ReadOnly condition As T = Nothing
        Public ReadOnly action As _do(Of AT, OT) = Nothing

        Public Sub New(ByVal condition As T, ByVal action As _do(Of AT, OT))
            assert(Not condition Is Nothing)
            assert(Not action Is Nothing)
            copy(Me.condition, condition)
            copy(Me.action, action)
        End Sub
    End Class

    Private ReadOnly selectors As hashmap(Of T, _do(Of AT, OT), _128) = Nothing
    Private ReadOnly default_action As _do(Of AT, OT) = Nothing

    Public Sub New(ByVal ParamArray selectors() As condition_action)
        Me.New(Nothing, selectors)
    End Sub

    Public Sub New(ByVal default_action As _do(Of AT, OT), ByVal ParamArray selectors() As condition_action)
        assert(Not selectors Is Nothing)
        assert(selectors.Length() > 0)
        Me.selectors = New hashmap(Of T, _do(Of AT, OT), _128)()
        For i As Int64 = 0 To selectors.Length() - 1
            assert(Me.selectors.find(selectors(i).condition) = Me.selectors.end())
            Me.selectors.insert(selectors(i).condition, selectors(i).action)
        Next
        copy(Me.default_action, default_action)
    End Sub

    Public Function execute(ByVal condition As T, ByVal arg As AT) As OT
        Dim it As hashmap(Of T, _do(Of AT, OT), _128).iterator = Nothing
        it = selectors.find(condition)
        If it = selectors.end() Then
            assert(Not default_action Is Nothing)
            Return default_action(arg)
        Else
            Return (+it).second(arg)
        End If
    End Function
End Class

Public Class switcher(Of T As IComparable(Of T), OT)
    Inherits switcher(Of T, Byte, OT)

    Public Shadows Class condition_action
        Inherits switcher(Of T, Byte, OT).condition_action

        Public Sub New(ByVal condition As T, ByVal action As _do(Of OT))
            MyBase.New(condition, cast(action))
        End Sub
    End Class

    Public Sub New(ByVal ParamArray selectors() As condition_action)
        MyBase.New(selectors)
    End Sub

    Public Sub New(ByVal default_action As _do(Of OT), ByVal ParamArray selectors() As condition_action)
        MyBase.New(cast(default_action), selectors)
    End Sub

    Public Shadows Function execute(ByVal condition As T) As OT
        Return MyBase.execute(condition, 0)
    End Function

    Private Shared Function cast(ByVal i As _do(Of OT)) As _do(Of Byte, OT)
        If i Is Nothing Then
            Return Nothing
        Else
            Return Function(ByRef a As Byte) As OT
                       Return i()
                   End Function
        End If
    End Function
End Class

Public Class switcher(Of T As IComparable(Of T))
    Inherits switcher(Of T, Byte)

    Public Shadows Class condition_action
        Inherits switcher(Of T, Byte).condition_action

        Public Sub New(ByVal condition As T, ByVal action As void)
            MyBase.New(condition, cast(action))
        End Sub
    End Class

    Public Sub New(ByVal ParamArray selectors() As condition_action)
        MyBase.New(selectors)
    End Sub

    Public Sub New(ByVal default_action As void, ByVal ParamArray selectors() As condition_action)
        MyBase.New(cast(default_action), selectors)
    End Sub

    Public Shadows Sub execute(ByVal condition As T)
        MyBase.execute(condition)
    End Sub

    Private Shared Function cast(ByVal i As void) As _do(Of Byte)
        If i Is Nothing Then
            Return Nothing
        Else
            Return Function() As Byte
                       i()
                       Return 0
                   End Function
        End If
    End Function
End Class
